package com.ume.supplier.cn.httputil.http

import com.google.gson.Gson
import com.xbxm.supplier.crm.httputil.http.BaseObserver
import com.xbxm.supplier.crm.httputil.http.ResponseInterceptor
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import okhttp3.MediaType
import okhttp3.RequestBody
import java.util.*

/**
 * Created by joe on 2018/7/2
 */
class HttpHelper private constructor() {
    private object Holder {
        val INSTANCE = HttpHelper()
    }

    fun addResponseInterceptor(interceptor: ResponseInterceptor) {
        BaseObserver.responseInterceptors.add(interceptor)
    }

    fun removeResponseInterceptor(interceptor: ResponseInterceptor) {
        BaseObserver.responseInterceptors.remove(interceptor)
    }

    companion object {
        val instance: HttpHelper by lazy { Holder.INSTANCE }
        fun getParams() = Params()
        var IS_MOCK = false
        var IS_ENABLE = true


        fun createBody(str: String): RequestBody =
            RequestBody.create(MediaType.parse("application/json; charset=utf-8"), str)

        var gson = Gson()
    }


    fun <T> request(
        observable: Observable<T>,
        callback: HttpCallback<T>,
        isMock: Boolean
    ): Disposable? {
        if (!IS_ENABLE) {
            return null
        }

        var disposable: Disposable? = null
        if (isMock && IS_MOCK) {
            val t = callback.getT()
            if (t is Mock) {
                callback.onSuccess(t.getMock() as T)
            }
            return null
        } else {
            observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(object : BaseObserver<T>() {
                    override fun onRequestError(message: String?, code: Int) {
//                            if (code == 4300) {
//                                if (App.topActivity() is SplashActicity) {
//                                    callback.onRequestError(message!!, code)
//                                } else {
//                                    EventBus.getDefault().post(LoginOutDate(code))
//                                }
//                            } else if (callback is HttpDialogCallback) {
//                                if (code == 404) {
////                                    callback.context.shortT("数据找不到")
//                                    callback.onRequestError("数据找不到", code)
//
//                                } else if (code == 500) {
////                                    callback.context.shortT("服务器秀逗了")
//                                    callback.onRequestError("服务器秀逗了", code)
//
//                                } else {
//                                    callback.onRequestError(message!!, code)
//                                }
//                            } else {
//                                if (code > 1000) {
//                                    callback.onRequestError("你用错callback了", code)
//                                } else {
//                                    callback.onRequestError(message.notNullStr(), code)
//                                }
//                            }

                    }

                    override fun onSuccess(response: T) {
                        callback.onSuccess(response)
                    }

                    override fun onFailure(reson: String?, err: Throwable) {
                        callback.onFailure(reson, err)
                    }

                    override fun onRequestStart(d: Disposable) {
                        callback.onBefore()
                        disposable = d
                    }

                })
            return disposable
        }
    }

    class Params {
        private val map: HashMap<String, String> = HashMap()

        fun put(key: String, value: Objects): Params {
            map[key] = value.toString()
            return this
        }

        fun put(key: String, value: Int): Params {
            map[key] = value.toString()
            return this
        }

        fun put(key: String, value: String): Params {
            map[key] = value.toString()
            return this
        }

        fun put(key: String, value: Float): Params {
            map[key] = value.toString()
            return this
        }

        fun put(key: String, value: Double): Params {
            map[key] = value.toString()
            return this
        }

        fun put(key: String, value: Long): Params {
            map[key] = value.toString()
            return this
        }

        fun build(): Map<String, String> = map
    }

    class LoginOutDate(val code: Int)

}
